package register;

import config.ConfigLoader;
import config.RPC;
import lombok.extern.log4j.Log4j;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.reflections.Reflections;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Log4j
public class ServiceRegistry {
    public static ZooKeeper zooKeeper;

    public static final Map<String, Object> REMOTE_OBJECTS = new HashMap<>();

    public static void initialize(String connectString) throws IOException {
        zooKeeper = new ZooKeeper(connectString, 15000, event -> {
            if (event.getState() == Watcher.Event.KeeperState.SyncConnected) {
                log.info("连接到ZooKeeper服务器");
            }
        });
    }

    public static void registerServiceWithRegistry(String serviceName, Object serviceInstance) {
        //检查父节点
        String registryPath = "/services";
        try {
            Stat stat = zooKeeper.exists(registryPath, false);
            if (stat == null) {
                zooKeeper.create(registryPath, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
        } catch (Exception e) {
            log.error("服务注册父节点失败: " + e.getMessage());
        }
        // 父节点路径
        String registryFatherPath = "/services/" + serviceName;
        try {
            // 确保服务的父节点存在
            if (zooKeeper.exists(registryFatherPath, false) == null) {
                zooKeeper.create(registryFatherPath, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
        } catch (Exception e) {
            log.error("创建服务父节点失败: " + e.getMessage());
        }

        try {
            // 获取服务地址
            String serviceAddress = ConfigLoader.getServerHost() + ":" + ConfigLoader.getServerPort();
            // 子节点路径，包括唯一标识
            String path = registryFatherPath + "/" + serviceAddress.replace(":", "_");

            // 检查服务节点是否存在
            if (zooKeeper.exists(path, false) == null) {
                // 使用EPHEMERAL模式注册服务实例
                zooKeeper.create(path, serviceAddress.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
                log.info("服务实例注册成功: " + serviceName + " at " + serviceAddress);

                // 启动心跳
                ServiceHeartbeat.startHeartbeat(path, serviceAddress);
            } else {
                log.info("该服务实例已注册: " + serviceName + " at " + serviceAddress);
            }
            REMOTE_OBJECTS.put(serviceName, serviceInstance);
        } catch (Exception e) {
            log.error("服务实例注册到ZooKeeper失败: " + e.getMessage());
        }
    }


    public static void scanAndRegisterServices() {
        Reflections reflections = new Reflections("service");
        Set<Class<?>> serviceClasses = reflections.getTypesAnnotatedWith(RPC.class);

        for (Class<?> serviceClass : serviceClasses) {
            try {
                Object serviceInstance = serviceClass.getDeclaredConstructor().newInstance();
                Class<?>[] interfaces = serviceClass.getInterfaces();
                for (Class<?> interf : interfaces) {
                    String interfaceName = interf.getName();
                    registerServiceWithRegistry(interfaceName, serviceInstance);
                }
            } catch (Exception e) {
                log.error("服务实例化或注册失败: " + e.getMessage());
            }
        }
    }

}

